package com.mall.b2c.service.impl;

import java.util.List;

import javax.annotation.Resource;

import com.mall.b2c.bean.SiteNoticeBean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.mall.b2c.dao.SiteNoticeDao;
import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.domain.member.SiteNoticeDomain;
import com.mall.b2c.domain.member.SiteNoticeTextDomain;
import com.mall.b2c.enums.SiteNoticeType;
import com.mall.b2c.service.MemberService;
import com.mall.b2c.service.SiteNoticeService;
import com.mall.b2c.service.SiteNoticeTextService;
import com.mall.common.exception.NoticeException;
import com.mall.common.hibernate.Finder;
import com.mall.common.service.impl.BaseServiceImpl;


/**
 * Service实现类 - 站内通知 - 接收者
 * @author 
 */
@Service("b2cSiteNoticeService")
@Transactional
public class SiteNoticeServiceImpl extends BaseServiceImpl<SiteNoticeDomain, Long> implements SiteNoticeService {
	
	@Resource private SiteNoticeTextService siteNoticeTextService;
	@Resource private MemberService memberService;

    @Resource private RedisTemplate<String, String> redisTemplateForNotice;
	
	@Resource
	public void setBaseDao(SiteNoticeDao siteNoticeDao) { 
		super.setBaseDao(siteNoticeDao); 
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void save(SiteNoticeTextDomain noticeText, Long[] memberIds,String sender) {
		//通知消息
		noticeText.setOperator(sender);
		siteNoticeTextService.persist(noticeText);
		
		//非系统消息保存
		if(noticeText.getType() != SiteNoticeType.GLOBLE){
			if(memberIds == null){
				throw new NoticeException("会员帐号为空");
			}
			List<MemberDomain> members = memberService.get(memberIds);
			if(!CollectionUtils.isEmpty(members)){
				for(MemberDomain member : members){
					SiteNoticeDomain notice = new SiteNoticeDomain();
					notice.setNoticeText(noticeText);
					notice.setMember(member);
					notice.setSender(sender);
//					redisTemplateForNotice.convertAndSend("member-" + member.getId(), new SiteNoticeBean(notice));
					this.persist(notice);
				}
			}
		}else{
			SiteNoticeDomain notice = new SiteNoticeDomain();
			notice.setNoticeText(noticeText);
			notice.setMember(null);
			notice.setSender(sender);
			redisTemplateForNotice.convertAndSend("member-all", new SiteNoticeBean(notice));
			this.persist(notice);
		}


	}

	@Override
	public List<MemberDomain> findMemberList(Long noticeTextId) {
		Finder finder = Finder.create("select sn.member from SiteNoticeDomain sn where sn.noticeText.id = :noticeId and sn.member is not null");
		finder.setParam("noticeId", noticeTextId);
		return finder.findHQLList();
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void edit(SiteNoticeTextDomain noticeText, String operator) {
		SiteNoticeTextDomain text = siteNoticeTextService.find(noticeText.getId());
		if(text == null){
			throw new NoticeException("该消息不存在");
		}
		text.setEnabledOuterUrl(noticeText.getEnabledOuterUrl());
		text.setOuterUrl(noticeText.getOuterUrl());
		text.setContent(noticeText.getContent());
		text.setOperator(operator);
		text.setTitle(noticeText.getTitle());
		text.setType(noticeText.getType());
		siteNoticeTextService.update(text);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public SiteNoticeDomain view(Long noticeTextId, Long memberId) {
		SiteNoticeDomain siteNotice = getSiteNotice(noticeTextId, memberId);
		if(siteNotice != null){
			if(!siteNotice.getIsRead()){
				siteNotice.setIsRead(true);
				this.update(siteNotice);
			}
		}else{
			MemberDomain member = memberService.find(memberId);
			if(member == null){
				throw new NoticeException("会员不存在");
			}
			SiteNoticeTextDomain noticeText = siteNoticeTextService.find(noticeTextId);
			if(noticeText == null || noticeText.getType() != SiteNoticeType.GLOBLE){
				throw new NoticeException("消息不存在");
			}
			siteNotice = new SiteNoticeDomain();
			siteNotice.setIsDelete(false);
			siteNotice.setIsRead(true);
			siteNotice.setMember(member);
			siteNotice.setNoticeText(noticeText);
			siteNotice.setSender(noticeText.getOperator());
			this.persist(siteNotice);
		}
		return siteNotice;
	}
	
	private SiteNoticeDomain getSiteNotice(Long noticeTextId, Long memberId){
		Finder finder = Finder.create("from SiteNoticeDomain sn where sn.noticeText.id = :noticeId and sn.member.id = :memberId ");
		finder.setParam("noticeId", noticeTextId);
		finder.setParam("memberId", memberId);
		Object obj = finder.findUniqueByHQL();
		if(obj == null){
			return null;
		}else{
			return (SiteNoticeDomain) obj;
		}
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void correlate(Long noticeTextId, Long[] memberIds, String operator) {
		Assert.notNull(noticeTextId, "消息ID不存在");
		Assert.notEmpty(memberIds, "会员IDS不存在");
		
		SiteNoticeTextDomain noticeText = siteNoticeTextService.find(noticeTextId);
		//非系统消息保存
		if(noticeText.getType() == SiteNoticeType.GLOBLE){
			throw new NoticeException("该消息类型为发送给所有人，无需要关联");
		}else{
			List<MemberDomain> members = memberService.get(memberIds);
			if(CollectionUtils.isEmpty(members)){
				throw new NoticeException("会员不存在");
			}
			boolean notExecute = true;
			for(MemberDomain member : members){
				if(getSiteNotice(noticeTextId, member.getId()) == null){
					SiteNoticeDomain notice = new SiteNoticeDomain();
					notice.setNoticeText(noticeText);
					notice.setMember(member);
					notice.setSender(operator);
					this.persist(notice);
					notExecute = false;
				}
			}
			if(notExecute){
				throw new NoticeException("已经关联过了");
			}
		}
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void delete(Long[] textIds, Long memberId) {
		Assert.notEmpty(textIds);
		
		for(int i = 0; i < textIds.length; i++){
			if(textIds[i] != null){
				SiteNoticeDomain notice = view(textIds[i], memberId);
				SiteNoticeTextDomain noticeText = notice.getNoticeText();
				if(noticeText.getType() == SiteNoticeType.PRIVATE){
					siteNoticeTextService.remove(noticeText);
				}else{
					notice.setIsDelete(true);
					this.update(notice);
				}
			}
		}
	}

}
